#include "widget_funcd_weather.h"
#include "ui_widget_funcd_weather.h"
#include <QNetworkReply>
#include <QJsonDocument>
#include <QJsonArray>
#include <QDebug>
#include <QAction>
#include <QString>
#include <QMenu>
#include <QMouseEvent>
#include <QMessageBox>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDateTime>
#include <QPainter>
#include "weathertool.h"

#define INCREMENT      3    /*<! 温度每升高或降低1℃, y 轴坐标的增量 */
#define POINT_RADIUS   3    /*<! 圆的半径 */
#define TEXT_OFFSET_X  12   /*<! */
#define TEXT_OFFSET_Y  12   /*<! */


Widget_funcD_Weather::Widget_funcD_Weather(QWidget *parent) :
    QWidget(parent),ui(new Ui::Widget_funcD_Weather)
    ,mNetAccessManager (new QNetworkAccessManager(this))
{
   ui->setupUi(this);
   ui->lblHighCurve->installEventFilter(this);
   ui->lblLowCurve->installEventFilter(this);
   QPixmap pixmap(":/res/type/BaoYu.png");
   if (pixmap.isNull()) {
       qDebug() << "Failed to load icon";
   }

    ui->btnSearch->setIcon(QPixmap(":/sousuo.png"));
    mWeekList << ui->lblWeek0 << ui->lblWeek1 << ui->lblWeek2 << ui->lblWeek3 << ui->lblWeek4 << ui->lblWeek5;
    mDateList << ui->lblDate0 << ui->lblDate1 << ui->lblDate2 << ui->lblDate3 << ui->lblDate4 << ui->lblDate5;
    mTypeList << ui->lblType0 << ui->lblType1 << ui->lblType2 << ui->lblType3 << ui->lblType4 << ui->lblType5;
    mTypeIconList <<ui->lblTypeIcon0<<ui->lblTypeIcon1<<ui->lblTypeIcon2<<ui->lblTypeIcon3<<ui->lblTypeIcon4<<ui->lblTypeIcon5;
   // mAqiList <<ui->lblQuality0<<ui->lblQuality1<< ui->lblQuality2<<ui->lblQuality3<<ui->lblQuality4<<ui->lblQuality5;
   // mFxList<<ui->lblFx0<<ui->lblFx1<<ui->lblFx2<<ui->lblFx3<<ui->lblFx4<<ui->lblFx5;
   // mFlList<<ui->lblFl0<<ui->lblFl1<< ui->lblFl2<<ui->lblFl3<<ui->lblFl4<<ui->lblFl5;
    // 天气类型 和图标的构造关系
    mTypeMap.insert("暴雪",":/res/type/BaoXue.png");
    mTypeMap.insert("暴雨",":/res/type/BaoYu. png");
    mTypeMap.insert("暴雨到大暴雨",":/res/type/BaoYuDaoDaBaoYu.png");
    mTypeMap.insert("大暴雨",":/res/type/DaBaoYu.png");
    mTypeMap.insert("大暴雨到特大暴雨",":/res/type/DaBaoYuDaoTeDaBaoYu.png");
    mTypeMap.insert("大到暴雪",":/res/type/DaDaoBaoXue.png");
    mTypeMap.insert("大雪",":/res/type/DaXue.png");
    mTypeMap.insert("大雨",":/res/type/DaYu.png");
    mTypeMap.insert("冻雨",":/res/type/DongYu.png");
    mTypeMap.insert("多云",":/res/type/DuoYun.png");
    mTypeMap.insert("浮沉",":/res/type/FuChen.png");
    mTypeMap.insert("雷阵雨",":/res/type/LeiZhenYu.png");
    mTypeMap.insert("雷阵雨伴有冰雹",":/res/type/LeiZhenYuBanYouBingBao.png");
    mTypeMap.insert("霾",":/res/type/Mai.png");
    mTypeMap.insert("强沙尘暴",":/res/type/QiangShaChenBao.png");
    mTypeMap.insert("晴",":/res/type/Qing.png");
    mTypeMap.insert("沙尘暴",":/res/type/ShaChenBao.png");
    mTypeMap.insert("特大暴雨",":/res/type/TeDaBaoYu.png");
    mTypeMap.insert("undefined",":/res/type/undefined.png");
    mTypeMap.insert("雾",":/res/type/Wu.png");
    mTypeMap.insert("小到中雪",":/res/type/XiaoDaoZhongXue.png");
    mTypeMap.insert("小到中雨",":/res/type/XiaoDaoZhongYu.png");
    mTypeMap.insert("小雪",":/res/type/XiaoXue.png");
    mTypeMap.insert("小雨",":/res/type/XiaoYu.png");
    mTypeMap.insert("雪",":/res/type/Xue.png");
    mTypeMap.insert("扬沙",":/res/type/YangSha.png");
    mTypeMap.insert("阴",":/res/type/Yin.png");
    mTypeMap.insert("雨",":/res/type/Yu.png");
    mTypeMap.insert("雨夹雪",":/res/type/YuJiaXue.png");
    mTypeMap.insert("阵雪",":/res/type/ZhenXue.png");
    mTypeMap.insert("阵雨",":/res/type/ZhenYu.png");
    mTypeMap.insert("中到大雪",":/res/type/ZhongDaoDaXue.png");
    mTypeMap.insert("中到大雨",":/res/type/ZhongDaoDaYu.png");
    mTypeMap.insert("中雪",":/res/type/ZhongXue.png");
    mTypeMap.insert("中雨",":/res/type/ZhongYu.png");
    // 关联 Http 响应信号和槽函数
    connect(mNetAccessManager, &QNetworkAccessManager::finished, this, &Widget_funcD_Weather::onRelied_slot);

    // 界面初始化前获取一次北京的天气数据
    // getWeatherInfo("101010100");
    getWeatherInfo("北京");

//    manager= new QNetworkAccessManager;
//    connect(manager, &QNetworkAccessManager::finished, this, [=](QNetworkReply *reply) {
//        if (reply->error() != QNetworkReply::NoError) {
//            qDebug() << "[Error] Network error:" << reply->errorString();
//            reply->deleteLater();
//            return;
//        }

//        const int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
//        if (statusCode != 200) {
//            qDebug() << "[Error] HTTP Status:" << statusCode;
//            reply->deleteLater();
//            return;
//        }

//                parseResponse(reply->readAll());
//                reply->deleteLater();
//    });

//    // 首次自动刷新
//    refreshWeather();

}

Widget_funcD_Weather::~Widget_funcD_Weather()
{
    delete ui;

}

void Widget_funcD_Weather::getWeatherInfo(QString cityName)
{
    // 根据城市名查找城市
    QString cityCode = WeatherTool::getCityCode(cityName);
    if(cityCode.isEmpty()) {
        QMessageBox::warning(this, "城市编码", "城市编码获取失败", QMessageBox::Ok);
        return;
    }

    QUrl url("http://t.weather.itboy.net/api/weather/city/" + cityCode);
    QNetworkRequest request(url);
    mNetAccessManager->get(request);
}

void Widget_funcD_Weather::parseJson(const QByteArray &byteArray)
{
    QJsonParseError err;
    QJsonDocument doc = QJsonDocument::fromJson(byteArray, &err);
    if(err.error != QJsonParseError::NoError) {
        qDebug() << "JSON parse error:" << err.errorString();
        return;
    }

    QJsonObject rootObj = doc.object();
    if (!rootObj.contains("data")) {
           qDebug() << "Missing 'data' key";
           return;
       }
    qDebug() << rootObj.value("message").toString() << endl;

    // 1. 解析日期和城市
    mToday.date = rootObj.value("date").toString();
    mToday.city = rootObj.value("cityInfo").toObject().value("city").toString();

    // 2.解析昨天
    QJsonObject dataObj=rootObj.value("data").toObject();
    QJsonObject yesterdayObj=dataObj.value("yesterday").toObject();
    mDay[0].week=yesterdayObj.value("week").toString();
    mDay[0].date=yesterdayObj.value("ymd").toString();
    mDay[0].type=yesterdayObj.value("type").toString();
    QString str=yesterdayObj.value("high").toString().split(" ").at(1);
    mDay[0].high=str.left(str.length()-1).toInt();
    str= yesterdayObj.value("low").toString().split(" ").at(1);
    mDay[0].low=str.left(str.length()-1).toInt();
    mDay[0].fx=yesterdayObj.value("fx").toString();
    mDay[0].fl=yesterdayObj.value("fl").toString();
    mDay[0].aqi=yesterdayObj["aqi"].toInt();//污染指数

    // 3.解析预报五天后的数据
    QJsonArray forcastArr=dataObj["forecast"].toArray();
    for(int i=0;i<5;i++){
        QJsonObject tempObj=forcastArr[i].toObject();
        mDay[i+1].week=tempObj.value("week").toString();
        mDay[i+1].date=tempObj.value("ymd").toString();
        mDay[i+1].type=tempObj.value("type").toString();
        str=tempObj.value("high").toString().split(" ").at(1);//高温 14℃
        mDay[i+1].high=str.left(str.length()-1).toInt();
        str= tempObj.value("low").toString().split(" ").at(1);
        mDay[i+1].low=str.left(str.length()-1).toInt();
        mDay[i+1].fx=tempObj.value("fx").toString();
        mDay[i+1].fl=tempObj.value("fl").toString();
        mDay[i+1].aqi=tempObj["aqi"].toInt();//污染指数
    }

    // 4.解析今天的数据
    mToday.ganmao=dataObj["ganmao"].toString();
    mToday.temp=dataObj["wendu"].toString();
    mToday.humudity=dataObj["shidu"].toString();
    mToday.pm25=dataObj["pm25"].toInt();
    mToday.quality=dataObj["quality"].toString();
    mToday.type=mDay[1].type;
    mToday.fl=mDay[1].fl;
    mToday.high=mDay[1].high;
    mToday.fx=mDay[1].fx;
    mToday.low=mDay[1].low;
    qDebug() << "解析后的天气数据：";
    for (int i = 0; i < 6; ++i) {
        qDebug() << "第"<< i << "天：" << mDay[i].date << mDay[i].high;
    }
    // 5. ui 渲染
    updateUI();

}

void Widget_funcD_Weather::updateUI()
{

    // 1. 更新日期 和 城市
    ui->lblDate->setText(QDateTime::fromString(mToday.date, "yyyyMMdd").toString("yyyy/MM/dd") + " " + mDay[1].week);
    ui->lblCity->setText(mToday.city);

    // 2. 更新今天
    ui->lblTemp->setText(mToday.temp + "°");
   // ui->lblLowHigh->setText(QString::number(mToday.low) + " ~ " + QString::number(mToday.high) + "℃");
    ui->lblGanMao->setText("感冒指数: " + mToday.ganmao);
    ui->lblWindFx->setText(mToday.fx);
    ui->lblWindFl->setText(mToday.fl);
    ui->lblPM25->setText(QString::number(mToday.pm25));
    ui->lblShiDu->setText(mToday.humudity);
    ui->lblQuality->setText(mToday.quality);
    ui->lblTypeIcon->setPixmap(mTypeMap[mToday.type]);

    // 3. 更新六天数据
    for(int i = 0; i < 6; ++i) {
        // 3.1 更新日期和时间
        mWeekList[i]->setText(QString("周") + mDay[i].week.right(1));
        QStringList ymdList = mDay[i].date.split("-");
        mDateList[i]->setText(ymdList[1] + "/" + ymdList[2]);

        // 3.2 更新天气类型
       mTypeList[i]->setText(mDay[i].type);
        mTypeIconList[i]->setPixmap(mTypeMap[mDay[i].type]);

    }
    ui->lblWeek0->setText("昨天");
    ui->lblWeek1->setText("今天");
    ui->lblWeek2->setText("明天");

    // 4.手动触发曲线 Label 的 Paint 事件
    ui->lblHighCurve->update();
    ui->lblLowCurve->update();

}

void Widget_funcD_Weather::paintHighCurve()
{
    qDebug() << "paintHighCurve() 被调用";

    // 是创建了一个QPainter对象，并将它绑定在ui->lblHighCurve小部件上
    // 操作 Painter 在 Label 上面作画
    QPainter painter(ui->lblHighCurve);

    // 抗锯齿渲染, 意味着渲染结果将更加平滑和精细
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
    qDebug() << "绘制高温曲线，当前标签尺寸："
             << ui->lblHighCurve->width() << "x" << ui->lblHighCurve->height();

    // 1. 获取 x 坐标
    int pointX[6] = {0};
    for(int i = 0; i < 6; ++i) {
        pointX[i] = mWeekList[i]->pos().x() + mWeekList[i]->width() / 2;
    }

    // 2. 获取 y 坐标
    // 2.1 得到六个高温度的平均值
    int tempSum = 0;
    int tempAve = 0;
    for(int i = 0; i < 6; ++i) {
        tempSum += mDay[i].high;
    }
    tempAve = tempSum / 6;

    // 2.2 计算 y 轴坐标
    int pointY[6] = {0};
    int yCenter = ui->lblHighCurve->height() / 2;
    for(int i = 0; i < 6; ++i) {
        pointY[i] = yCenter - (mDay[i].high - tempAve) * INCREMENT;
    }

    // 3. 开始绘制
    // 3.1 初始化画笔相关
    QPen pen = painter.pen();
    pen.setWidth(1);
    pen.setColor(QColor(255, 170, 0));
    painter.setPen(pen);
    painter.setBrush(QColor(255, 170, 0));   // 园内部填充

    // 3.2 画点、写文本
    for(int i = 0; i < 6; ++i) {

        // 显示温度点
        painter.drawEllipse(QPoint(pointX[i], pointY[i]*1.5), POINT_RADIUS, POINT_RADIUS);

        // 显示温度文本
        painter.drawText(pointX[i] - TEXT_OFFSET_X, pointY[i] - TEXT_OFFSET_Y, QString::number(mDay[i].high) + "°");
    }

    // 3.3 绘制曲线
    for(int i = 0; i < 5; ++i) {
        if(i == 0) {
            pen.setStyle(Qt::DotLine);    // 画虚线
            painter.setPen(pen);

        } else {
            pen.setStyle(Qt::SolidLine);  // 画实线
            painter.setPen(pen);
        }
        painter.drawLine(pointX[i], pointY[i]*1.5, pointX[i+1], pointY[i+1]*1.5);
    }
}

void Widget_funcD_Weather::paintLowCurve()
{
    // 是创建了一个QPainter对象，并将它绑定在ui->lblHighCurve小部件上
    // 操作 Painter 在 Label 上面作画

    qDebug() << "paintHighCurve() 被调用";
    QPainter painter(ui->lblLowCurve);

    // 抗锯齿渲染, 意味着渲染结果将更加平滑和精细
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setRenderHint(QPainter::SmoothPixmapTransform, true);

    // 1. 获取 x 坐标

    int pointX[6] = {0};
    for(int i = 0; i < 6; ++i) {

        pointX[i] = mWeekList[i]->pos().x() + mWeekList[i]->width() / 2;
         qDebug() << "pointX["<< i << "] = " << pointX[i];
    }

    // 2. 获取 y 坐标
    // 2.1 得到六个高温度的平均值
    int tempSum = 0;
    int tempAve = 0;
    for(int i = 0; i < 6; ++i) {
        tempSum += mDay[i].high;
    }
    tempAve = tempSum / 6;

    // 2.2 计算 y 轴坐标
    int pointY[6] = {0};
    int yCenter = ui->lblLowCurve->height() / 2;
    for(int i = 0; i < 6; ++i) {
        pointY[i] = yCenter - (mDay[i].low - tempAve) * INCREMENT;
    }

    // 3. 开始绘制
    // 3.1 初始化画笔相关
    QPen pen = painter.pen();
    pen.setWidth(1);
    pen.setColor(QColor(44,107,151));
    painter.setPen(pen);
    painter.setBrush(QColor(44,107,151));   // 园内部填充

    // 3.2 画点、写文本
    for(int i = 0; i < 6; ++i) {

        // 显示温度点
        painter.drawEllipse(QPoint(pointX[i], pointY[i]*0.5), POINT_RADIUS, POINT_RADIUS);

        // 显示温度文本
        painter.drawText(pointX[i] - TEXT_OFFSET_X, pointY[i] - TEXT_OFFSET_Y, QString::number(mDay[i].low) + "°");
    }

    // 3.3 绘制曲线
    for(int i = 0; i < 5; ++i) {
        if(i == 0) {
            pen.setStyle(Qt::DotLine);    // 画虚线
            painter.setPen(pen);

        } else {
            pen.setStyle(Qt::SolidLine);  // 画实线
            painter.setPen(pen);
        }
        painter.drawLine(pointX[i], pointY[i]*0.5, pointX[i+1], pointY[i+1]*0.5);

    }
}

//void Widget_funcD_Weather::contextMenuEvent(QContextMenuEvent *event)
//{
//    // 弹出右键菜单
//    mExitMenu->exec(QCursor::pos());
//}

bool Widget_funcD_Weather::eventFilter(QObject *watched, QEvent *event)
{
    if(watched == ui->lblHighCurve && event->type() == QEvent::Paint) {
        paintHighCurve();
    } else if(watched == ui->lblLowCurve && event->type() == QEvent::Paint) {
        paintLowCurve();
    }

    return QWidget::eventFilter(watched, event);
}

void Widget_funcD_Weather::onRelied_slot(QNetworkReply *reply)
{
    // 获取状态码
    int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    qDebug() << statusCode << endl;
    qDebug() << "operation: " << reply->operation() << endl;
    qDebug() << "status code: " << statusCode << endl;
    qDebug() << "url: " <<reply->url() << endl;
    qDebug() << "raw header: " << reply->rawHeaderList() << endl;

    if(reply->error() != QNetworkReply::NoError || statusCode != 200) {
        qDebug() << reply->errorString().toLatin1().data() << endl;
        QMessageBox::warning(this, "天气", "请求数据失败", QMessageBox::Ok);
    } else {
        QByteArray byteArray = reply->readAll();
        qDebug() << "read all : " << byteArray.data();

        // 解析 JSON 数据
        parseJson(byteArray);
    }

    // 堆上内存释放
    reply->deleteLater();
}

//void Widget_funcD_Weather::refreshWeather()
//{
//    qDebug() << "\n--- 开始请求天气数据 ---";
//    manager->get(QNetworkRequest(QUrl("http://t.weather.itboy.net/api/weather/city/101010100")));
//}

//void Widget_funcD_Weather::parseResponse(const QByteArray &data)
//{
//    QJsonParseError error;
//    QJsonDocument doc = QJsonDocument::fromJson(data, &error);

//    if (error.error != QJsonParseError::NoError) {
//        qDebug() << "[Error] JSON 解析失败:" << error.errorString();
//        return;
//    }

//    const QJsonObject root = doc.object();
//    const QJsonObject cityInfo = root["cityInfo"].toObject();
//    const QJsonObject dataObj = root["data"].toObject();

//    // 解析基础数据
//    currentData.city = cityInfo["city"].toString();
//    currentData.wendu = dataObj["wendu"].toString();

//    // 解析天气预报
//    currentData.forecast.clear();
//    const QJsonArray forecastArray = dataObj["forecast"].toArray();
//    for (const QJsonValue &val : forecastArray) {
//        const QJsonObject obj = val.toObject();
//        ForecastDay day;
//        day.date = obj["date"].toString();
//        day.week = obj["week"].toString();
//        day.high = obj["high"].toString();
//        day.low = obj["low"].toString();
//        day.type = obj["type"].toString();
//        currentData.forecast.append(day);
//    }

//    printWeatherData();
//}

//void Widget_funcD_Weather::printWeatherData() const
//{
//    qDebug() << "\n=== 最新天气数据 ===";
//    qDebug() << "城市:" << currentData.city;
//    ui->label_2->setText(currentData.city);
//    qDebug() << "当前温度:" << currentData.wendu << "℃";
//    ui->label_10->setText(currentData.wendu+"℃");
//    ui->label_4->setText(currentData.wendu+"°");
//    qDebug() << "\n未来天气预报:";

//    for (const ForecastDay &day : currentData.forecast) {
//        qDebug().nospace()
//            << "┃ "
//            << day.date.leftJustified(10, ' ')    // 日期（10字符宽度）
//            << "│ "
//            << day.type.leftJustified(4, ' ')     // 天气类型（4字符宽度）
//            << "│ "
//            << day.low.mid(3).rightJustified(5)   // 低温（截取数值部分）
//            << " - "
//            << day.high.mid(3).leftJustified(5)   // 高温
//            << " │";
//    }
//    qDebug() << "===================\n";
//}


void Widget_funcD_Weather::on_btnSearch_clicked()
{
    QString cityName = ui->leCity->text().trimmed();
    if(cityName.isEmpty()) {
        QMessageBox::warning(this, "城市", "请输入城市名", QMessageBox::Ok);
        return;
    }

    getWeatherInfo(cityName);
}

void Widget_funcD_Weather::update() {
    getWeatherInfo(ui->lblCity->text().trimmed());
    ui->lblHighCurve->update();
    ui->lblLowCurve->update();
}
